home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 21
/
CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso
/
CUCD
/
Programming
/
Python-1.4
/
Source
/
Amiga
/
Python_netlib
/
_chkufb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-16
|
3KB
|
156 lines
RCS_ID_C="$Id: _chkufb.c,v 4.1 1994/09/29 23:09:02 jraja Exp $";
/*
* _chkufb.c - return struct ufb * from a file handle (SAS/C)
*
* Copyright © 1994 AmiTCP/IP Group,
* Network Solutions Development Inc.
* All rights reserved.
*/
#include <ios1.h>
#include <stdlib.h>
#include <errno.h>
#include <bsdsocket.h>
#include <sys/cdefs.h>
#include <amitcp/socketbasetags.h>
#include <syslog.h>
#include "libcheck.h"
extern unsigned long __fmask;
extern int (*__closefunc)(int);
long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
/*
* The initializator priority is just above the standard I/O, so that this
* will be called after the standard I/O is initialized
*/
long __stdargs
_STI_510_install_AmiTCP_callback(void)
{
/* needs bsdsocket.library -- I.J. */
if(checkbsdsocketlib())
{
if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
syslog(LOG_ERR, "Cannot install fdCallback!");
#if __VERSION__ > 6 || __REVISION__ > 3
return 1;
#else
exit(20);
#endif
}
}
else PyErr_Clear(); /* don't report error if socketlib not found */
/*
* Set up __closefunc (which is used at stdio cleanup)
*/
__closefunc = __close;
/*
* Set default file mask to UNIX style
*/
__fmask = 0644;
return 0;
}
long ASM SAVEDS
fdCallback(REG(d0) int fd, REG(d1) int action)
{
struct UFB *ufb;
int fd2;
#ifdef DEBUG
syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
#endif
switch (action) {
case FDCB_FREE:
ufb = __chkufb(fd);
if (ufb == NULL)
return EBADF;
if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
#ifdef DEBUG
syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
#endif
return ENOTSOCK;
}
ufb->ufbflg = 0;
return 0;
case FDCB_ALLOC:
do {
ufb = __allocufb(&fd2);
if (ufb == NULL)
return ENOMEM;
#ifdef DEBUG
if (fd2 > fd) {
syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
return EINVAL;
}
#endif
ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
ufb->ufbfh = NULL; /* no file handle */
ufb->ufbfn = NULL; /* no name */
} while (fd2 < fd);
return 0;
case FDCB_CHECK:
ufb = __chkufb(fd);
if (ufb != NULL && ufb->ufbflg != 0)
return EBADF;
return 0;
default:
#ifdef DEBUG
syslog(LOG_ERR, "fdCallback: invalid action.");
#endif
return EINVAL;
}
}
struct UFB *
__chkufb(int fd)
{
struct UFB *ufb;
/* a single element cache */
static struct UFB *last_ufb = NULL;
static int last_fd = -1;
_OSERR = 0;
if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
errno = EBADF;
return NULL;
}
/*
* Check the cache first
*/
if (fd == last_fd)
return last_ufb;
last_fd = fd; /* update cache */
ufb = __ufbs;
while (fd > 0 && ufb != NULL) {
fd--;
ufb = ufb->ufbnxt;
}
last_ufb = ufb; /* update cache */
if (ufb == NULL) {
last_fd = -1; /* invalidate cache */
errno = EIO;
return NULL;
}
else
return ufb;
}